#Towers classes

import common
import bullet
import effects

class Tower:
    name = "" # name of the tower
    desc = "" # short description of the tower
    size = [32,32] # pixel size
    state = 0 # upgrade level
    attack_dmg = 0 # base damage done to creeps
    sight = 0 # max distance or range able to hit
    cost = 0 # resources needed to purchase or upgrade
    targetrange = 0 # 1=ground, 2=air, 3=ground+air
    reload_rate = 40 # attack speed every n^th tick 
    splash = 0 # pixel radius around target
    effect = None # magic effect done to target or area
    img_name ="32xPO"
    targetmodes = ['leasthp','mosthp','fastest','nearest','farthest','group']
    x_offset = -size[0]/2
    y_offset = -size[1]/2
    
    def __init__(self,pos,owner):
        self.x, self.y = pos
        self.owner = owner
        
        self.targetmode = 'leasthp'
        self.target = None
        self.creeplist = [] # all creeps in range
        self.bulletlist = [] # all bullets from tower
        self.image = common.images[self.img_name].copy()
        self.reload_tick = self.reload_rate
        self.selected = False
        self.rect = [self.x-self.size[0]/2, self.y-self.size[1]/2,self.size[0],self.size[1]]

    def set_target(self):
        if len(self.creeplist) <> 0:
            if self.targetmode == 'leasthp':
                self.target = common.sort_health(self.creeplist)[0]
                
            elif self.targetmode == 'mosthp':
                self.target = common.sort_health(self.creeplist)[-1]
                                  
            elif self.targetmode == 'nearest': 
                self.target = common.sort_dist(self, self.creeplist)[0]
                
            elif self.targetmode == 'farthest':
                self.target = common.sort_dist(self, self.creeplist)[-1]
                
            elif self.targetmode == 'group':
                self.target = common.get_keystone(self.creeplist)
                
            elif self.targetmode == 'fastest':
                self.target = common.sort_speed(self.creeplist)[-1]
        else:
            self.target = None
        
    def set_targetmode(self,newmode):
        self.targetmode = newmode
        
    def sell(self,user):
        user.money += self.cost
        
    def set_creeplist(self,creeps):   ## TODO: needs work
        self.creeplist = []
        
        for creep in creeps:
            if common.get_dist_sqr(self.x - creep.x, self.y-creep.y) <= self.sight**2:
                self.creeplist.append(creep)
        
    def fire(self):
        if self.reload_tick > 0:
            self.reload_tick -= 1
        if self.target <> None:
            if self.reload_tick <= 0:
                self.bulletlist.append(bullet.Ammo(self,self.target))
                self.reload_tick = self.reload_rate
            
    def place(self):  # if i want to display a reason for a False, change to variable and return at the end
        if self.owner.money < self.cost:
            return False
        
        if self.x +self.size[0]-16 > 608 or self.y +self.size[1]-16 >608 or self.x  <= 0 or self.y <= 0:
            return False
            
        for tower in self.owner.twr_list:
            if common.get_dist_sqr(tower.x-self.x, tower.y-self.y) <= 512:
                return False        
                       
        for n in range(0,len(common.path)):
            px0 = common.path[n][0]
            py0 = common.path[n][1]
            if n == len(common.path)-1:
                px1 = px0-1
                py1 = py0
            else:
                px1 = common.path[n+1][0]
                py1 = common.path[n+1][1]
                
            if common.get_dist_sqr(px0-self.x,py0-self.y) <= 128:
                return False
            if common.test_circleline((px0,py0),(px1,py1),(self.x,self.y),16) == True:
                return False
                
        return True

        
class Slingshot(Tower):
    name = "Slingshot Tower"
    description = "Fires light weight rocks with a small range"
    attack_dmg = 2.0
    sight = 60
    cost = 2 
    targetrange = 3
    reload_rate = 40
    img_name = "slingshot"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
                            
class LW_Arrow(Tower):
    #size = [16,16]            
    #x_offset = -size[0]/2     #only need this if size is not Baseclass size
    #y_offset = -size[1]/2     #only need this if size is not Baseclass size
    
    name = "Light Weight Arrow Tower"
    description = "Fires light weight arrows at a single target"
    attack_dmg = 3.0
    sight = 60
    cost = 4 
    targetrange = 3
    reload_rate = 30    
    img_name = "lwarrow"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)

class HW_Arrow(Tower):
    name = "Heavy Weight Arrow Tower"
    description = "Fires heavy arrows at a single target"
    attack_dmg = 8.0
    sight = 75
    cost = 7 
    targetrange = 3
    reload_rate = 45
    img_name = "hwarrow"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)

class Catapult(Tower):
    name = "Catapult Tower"
    description = "Fires large rocks at a target causing large amounts of damage"
    attack_dmg = 25.0
    sight = 100
    cost = 15
    targetrange = 3
    reload_rate = 60
    img_name = "catapult"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
        
class Spike(Tower):
    name = "Spike Tower"
    description = "Short range tower but extremely fast firing rate"
    attack_dmg = 2.5
    sight = 50
    cost = 13 
    targetrange = 3
    reload_rate = 10
    img_name = "spike"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
        self.targetmode = 'nearest'
        
class Sludge(Tower):
    name = "Sludge Tower"
    description = "Shoots blobs of sludge that slows the enemy by 50% lasting 5 seconds but does very little damage"
    attack_dmg = 5.0
    sight = 70
    cost = 10 
    targetrange = 3
    reload_rate = 45
    img_name = "sludge"
    effect = effects.Slow
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
        self.targetmode = 'fastest'
        
class Fire(Tower):
    name = "Fire Tower"
    description = "Burns the enemy doing large damage over time"
    attack_dmg = 8.0
    sight = 150
    cost = 30 
    targetrange = 3
    reload_rate = 30
    effect = effects.Burn
    img_name = "fire"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
        self.targetmode = 'mosthp'
class Sniper(Tower):
    name = "Sniper Tower"
    description = "This tower does exactly what it's named"
    attack_dmg = 80.0
    sight = 200
    cost = 100 
    targetrange = 3
    reload_rate = 80
    img_name = "sniper"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)
        self.targetmode = 'farthest'
        
class Rapidfire(Tower):
    name = "Rapidfire Tower"
    description = "A hard hitting fast tower"
    attack_dmg = 50.0
    sight = 125
    cost = 45 
    targetrange = 3
    reload_rate = 15
    img_name = "rapidfire"
    
    def __init__(self,pos,owner):
        Tower.__init__(self,pos,owner)       